<script lang="ts" setup>
import { isFunction } from 'lodash-es';

import type { TableActionType } from '@/components/table';
import { BasicTable } from '@/components/table';
import { BasicModal, useModal } from '@/components/modal';
import { BasicForm, type FormActionType } from '@/components/form';
import type { BasicCrudProps } from '@/components/crud/src/props';
import { useDataActionButtons } from '@/components/crud/src/hooks/use-data-action-buttons';
import { type CrudContext, createCrudContext } from '@/components/crud/src/context/use-crud-context';
import { useCrudButtons } from '@/components/crud/src/hooks/use-crud-buttons';
import { filterObjectParams } from '@/utils/common';
import { useToolBarActionButtons } from '@/components/crud/src/hooks/use-tool-bar-action-buttons';
import ToolBarAction from '@/components/crud/src/components/tool-bar-action.vue';

const props = withDefaults(defineProps<BasicCrudProps>(), {
  pagination: true,
  searchable: true,
  modalWidth: '50vw',
  keyField: 'id',
});
const emits = defineEmits<{
  (e: 'fetchSuccess', res: any): void;
}>();

const tableInstance = ref<TableActionType>();
const searchFormInstance = ref<FormActionType>();
const formInstance = ref<FormActionType>();

const formScene = ref<'create' | 'modify'>('create');

const [register, { openModal, closeModal, setLoading }] = useModal({
  title: '新增',
});

/**
 * 表格数据获取事件
 */
function handleTableFetchSuccess(res: any) {
  emits('fetchSuccess', res);
}

/**
 * 表格选中数据
 */
const selectedValues = ref<Array<string | number>>([]);
function handleTableCheck(values: Array<string | number>) {
  selectedValues.value = values;
}

/**
 * crud按钮
 */
const { handleCreate, handleModify, handleDelete, handleBatchDelete } = useCrudButtons(
  props,
  formInstance,
  tableInstance,
  openModal,
  formScene,
  selectedValues,
);

/**
 * curd 上下文
 */
const context = reactiveComputed<CrudContext>(() => {
  return {
    props,
    toolbarActionButtons: props.toolbarActionButtons ?? [],
    dataActionButtons: props.dataActionButtons ?? [],
    handleCreate,
    handleModify,
    handleDelete,
    handleBatchDelete,
  };
});
createCrudContext(context);

/**
 * 搜索相关
 */
const searchFormData = ref<Recordable>();
function handleSearch(data: Recordable) {
  searchFormData.value = data;
}
function handleReset() {}

/**
 * 表格查询参数
 */
const searchParams = computed(() => {
  const requestParams = props.requestParams ? filterObjectParams(props.requestParams) : {};
  return {
    ...searchFormData.value,
    ...requestParams,
  };
});

/**
 * tool-bar 按钮
 */
const toolBarActionButtons = useToolBarActionButtons(context, selectedValues);

/**
 * action 按钮
 */
const dataActionButtons = useDataActionButtons(context);

/**
 * 提交表单
 */
async function handleSubmit() {
  // TODO 校验表单
  const formData = formInstance.value?.getFieldsValue();
  if (formScene.value === 'create' && isFunction(props.createRequest)) {
    try {
      await props.createRequest(formData);
      closeModal();
      tableInstance.value?.reload(searchParams.value);
    } finally {
      setLoading(false);
    }
  }

  if (formScene.value === 'modify' && isFunction(props.modifyRequest)) {
    try {
      await props.modifyRequest(formData);
      closeModal();
      tableInstance.value?.reload(searchParams.value);
    } finally {
      setLoading(false);
    }
  }
}

defineExpose({
  tableInstance,
  formInstance,
});
</script>

<template>
  <div>
    <NCard v-if="props.searchable" class="mb-3">
      <BasicForm
        ref="searchFormInstance"
        inline
        layout="inline"
        label-width="80"
        show-action-button-group
        show-submit-button
        show-reset-button
        show-advanced-button
        :grid-props="{ cols: 4 }"
        :schemas="props.searchSchemas ?? []"
        @submit="handleSearch"
        @reset="handleReset"
      />
    </NCard>

    <NCard>
      <BasicTable
        ref="tableInstance"
        :tree-table="props.treeTable"
        :tree-field="props.treeField"
        :pagination="props.pagination"
        :columns="props.tableColumns"
        :request="props.request"
        :request-params="searchParams"
        :row-key="(row: Recordable) => row.roleId"
        :action-buttons="dataActionButtons"
        :value-field="props.keyField"
        @check="handleTableCheck"
        @fetch-success="handleTableFetchSuccess"
      >
        <template #tableTitle>
          <ToolBarAction :action-buttons="toolBarActionButtons" />
        </template>
      </BasicTable>
    </NCard>

    <BasicModal :width="props.modalWidth" @register="register" @confirm="handleSubmit">
      <template #default>
        <BasicForm
          ref="formInstance"
          :grid-props="{ cols: 2 }"
          :schemas="props.formSchemas"
        />
      </template>
    </BasicModal>
  </div>
</template>

<style lang="less" scoped></style>
